fix parsing of nmea hms fields. (#770)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Tue, 23 Nov 2021 16:40:30 +0000 (09:40 -0700)
committerGitHub <noreply@github.com>
Tue, 23 Nov 2021 16:40:30 +0000 (09:40 -0700)
nmea.cc
reference/track/nmeadatetime.csv [new file with mode: 0644]
reference/track/nmeadatetime.nmea [new file with mode: 0644]
testo.d/nmea.test

diff --git a/nmea.cc b/nmea.cc
index 8c55f9b93cb6b66fe64d7361e5c283b65ba4ccf0..92d284c08ddad16d6abb2e992d43ab1587dbcba5 100644 (file)
--- a/nmea.cc
+++ b/nmea.cc
@@ -346,8 +346,25 @@ NmeaFormat::nmea_set_waypoint_time(Waypoint* wpt, QDateTime* prev, const QDate&
 
 QTime NmeaFormat::nmea_parse_hms(const QString& str)
 {
-  QString format = str.contains('.')? "hhmmss.zzz" : "hhmmss";
-  return QTime::fromString(str, format);
+  // QTime::fromString z expects 1 to 3 digit fractional part of seconds.
+  // It specifically does not accept 0 digits or > 3 digits.
+  // QTime::fromString zzz expects exactly 3 digits representing milliseconds.
+  QTime retval; /* invalid time */
+  const QStringList parts = str.trimmed().split('.');
+  if ((parts.size() == 1) || (parts.size() == 2)) {
+    retval = QTime::fromString(parts.at(0), "hhmmss");
+    if (retval.isValid() && parts.size() == 2) {
+      bool ok;
+      // prepend "0.".  prepending "." won't work if there are no trailing digits.
+      long msec = lround(1000.0 * QString("0.%1").arg(parts.at(1)).toDouble(&ok));
+      if (ok) {
+        retval = retval.addMSecs(msec);
+      } else {
+        retval = QTime(); /* invalid time */
+      }
+    }
+  }
+  return retval;
 }
 
 void
@@ -876,7 +893,7 @@ NmeaFormat::nmea_parse_one_line(const QByteArray& ibuf)
       if (ok) {
         int ckval = nmea_cksum(tbuf.mid(1, ckidx - 1));
         if (ckval != ckcmp) {
-          Warning().nospace() <<  Qt::hex << "Invalid NMEA checksum.  Computed 0x" << ckval << " but found 0x" << ckcmp << ".  Ignoring sentence.";
+          Warning().nospace() << qSetFieldWidth(2) << qSetPadChar('0') <<  Qt::hex << "Invalid NMEA checksum.  Computed 0x" << ckval << " but found 0x" << ckcmp << ".  Ignoring sentence.";
           return;
         }
         checked = true;
diff --git a/reference/track/nmeadatetime.csv b/reference/track/nmeadatetime.csv
new file mode 100644 (file)
index 0000000..ecf9a5a
--- /dev/null
@@ -0,0 +1,20 @@
+No,Latitude,Longitude,Altitude,Speed,Course,FIX,HDOP,Satellites,Date,Time\r
+1,-42.832757,147.445532,,0.01,0.0,,,,2019/10/23,22:25:07\r
+2,-42.832757,147.445532,30.0,0.01,0.0,"3d",0.96,9,2019/10/23,22:25:08\r
+3,-42.832757,147.445531,30.0,0.00,0.0,"3d",0.96,9,2019/10/23,22:25:09\r
+4,-42.832758,147.445531,30.0,0.03,0.0,"3d",0.96,8,2019/10/23,22:25:10.100\r
+5,-42.832758,147.445530,30.0,0.01,0.0,"3d",0.86,9,2019/10/23,22:25:11.010\r
+6,-42.832758,147.445529,30.1,0.02,0.0,"3d",0.96,9,2019/10/23,22:25:12.001\r
+7,-42.832758,147.445529,30.2,0.02,0.0,"3d",0.96,9,2019/10/23,22:25:13\r
+8,-42.832758,147.445529,30.2,0.02,0.0,"3d",0.96,9,2019/10/23,22:25:14.001\r
+9,-42.832758,147.445529,30.2,0.02,0.0,"3d",0.96,9,2019/10/23,00:00:00\r
+10,-42.832758,147.445529,30.2,0.02,0.0,"3d",0.96,9,2019/10/23,22:25:16\r
+11,-42.832758,147.445529,30.2,0.02,0.0,"3d",0.96,9,2019/10/23,22:25:17\r
+12,-42.832758,147.445529,30.2,0.02,0.0,"3d",0.96,9,2019/10/23,22:25:18\r
+13,-42.832758,147.445529,30.2,0.02,0.0,"3d",0.96,9,2019/10/23,22:25:19\r
+14,-42.832758,147.445529,30.2,0.02,0.0,"3d",0.96,9,2019/10/23,22:25:20\r
+15,-42.832758,147.445529,30.2,0.02,0.0,"3d",0.96,9,2019/10/23,22:25:21\r
+16,-42.832758,147.445529,30.2,0.02,0.0,"3d",0.96,9,2019/10/23,22:25:22\r
+17,-42.832758,147.445529,30.2,0.02,0.0,"3d",0.96,9,2019/10/23,00:00:00\r
+18,-42.832758,147.445529,30.2,0.02,0.0,"3d",0.96,9,2019/10/23,22:25:24\r
+19,-42.832758,147.445529,30.2,0.02,0.0,"3d",0.96,9,2019/10/23,00:00:00\r
diff --git a/reference/track/nmeadatetime.nmea b/reference/track/nmeadatetime.nmea
new file mode 100644 (file)
index 0000000..79ca1b2
--- /dev/null
@@ -0,0 +1,38 @@
+$GPRMC,222507.00,A,4249.96542,S,14726.73195,E,0.013,,231019,,,A*6F
+$GPGGA,222507.00,4249.96542,S,14726.73195,E,1,09,0.96,30.0,M,-8.8,M,,*61
+$GPRMC,222508,A,4249.96545,S,14726.73187,E,0.027,,231019,,,A*4D
+$GPGGA,222508,4249.96545,S,14726.73187,E,1,09,0.96,30.0,M,-8.8,M,,*44
+$GPRMC,222509.,A,4249.96546,S,14726.73184,E,0.006,,231019,,,A*61
+$GPGGA,222509.,4249.96546,S,14726.73184,E,1,08,0.96,30.0,M,-8.8,M,,*6A
+$GPRMC,222510.1,A,4249.96547,S,14726.73179,E,0.055,,231019,,,A*5D
+$GPGGA,222510.1,4249.96547,S,14726.73179,E,1,09,0.86,30.0,M,-8.8,M,,*50
+$GPRMC,222511.01,A,4249.96548,S,14726.73174,E,0.021,,231019,,,A*6D
+$GPGGA,222511.01,4249.96548,S,14726.73174,E,1,09,0.96,30.1,M,-8.8,M,,*63
+$GPRMC,222512.001,A,4249.96551,S,14726.73171,E,0.042,,231019,,,A*56
+$GPGGA,222512.001,4249.96551,S,14726.73171,E,1,09,0.96,30.2,M,-8.8,M,,*5E
+$GPRMC,222513.0001,A,4249.96551,S,14726.73171,E,0.042,,231019,,,A*67
+$GPGGA,222513.0001,4249.96551,S,14726.73171,E,1,09,0.96,30.2,M,-8.8,M,,*6F
+$GPRMC,222514.0009,A,4249.96551,S,14726.73171,E,0.042,,231019,,,A*68
+$GPGGA,222514.0009,4249.96551,S,14726.73171,E,1,09,0.96,30.2,M,-8.8,M,,*60
+$GPRMC,222515.x,A,4249.96551,S,14726.73171,E,0.042,,231019,,,A*18
+$GPGGA,222515.x,4249.96551,S,14726.73171,E,1,09,0.96,30.2,M,-8.8,M,,*10
+$GPRMC,222516,A,4249.96551,S,14726.73171,E,0.042,,231019,,,A*4D
+$GPGGA,222516,4249.96551,S,14726.73171,E,1,09,0.96,30.2,M,-8.8,M,,*45
+$GPRMC,222517 ,A,4249.96551,S,14726.73171,E,0.042,,231019,,,A*6C
+$GPGGA,222517 ,4249.96551,S,14726.73171,E,1,09,0.96,30.2,M,-8.8,M,,*64
+$GPRMC,222518,A,4249.96551,S,14726.73171,E,0.042,,231019,,,A*43
+$GPGGA,222518,4249.96551,S,14726.73171,E,1,09,0.96,30.2,M,-8.8,M,,*4B
+$GPRMC, 222519,A,4249.96551,S,14726.73171,E,0.042,,231019,,,A*62
+$GPGGA, 222519,4249.96551,S,14726.73171,E,1,09,0.96,30.2,M,-8.8,M,,*6A
+$GPRMC,222520,A,4249.96551,S,14726.73171,E,0.042,,231019,,,A*48
+$GPGGA,222520,4249.96551,S,14726.73171,E,1,09,0.96,30.2,M,-8.8,M,,*40
+$GPRMC,222521.0 ,A,4249.96551,S,14726.73171,E,0.042,,231019,,,A*77
+$GPGGA,222521.0 ,4249.96551,S,14726.73171,E,1,09,0.96,30.2,M,-8.8,M,,*7F
+$GPRMC,222522,A,4249.96551,S,14726.73171,E,0.042,,231019,,,A*4A
+$GPGGA,222522,4249.96551,S,14726.73171,E,1,09,0.96,30.2,M,-8.8,M,,*42
+$GPRMC,222523.0x,A,4249.96551,S,14726.73171,E,0.042,,231019,,,A*2D
+$GPGGA,222523.0x,4249.96551,S,14726.73171,E,1,09,0.96,30.2,M,-8.8,M,,*25
+$GPRMC,222524,A,4249.96551,S,14726.73171,E,0.042,,231019,,,A*4C
+$GPGGA,222524,4249.96551,S,14726.73171,E,1,09,0.96,30.2,M,-8.8,M,,*44
+$GPRMC,.1,A,4249.96551,S,14726.73171,E,0.042,,231019,,,A*52
+$GPGGA,.1,4249.96551,S,14726.73171,E,1,09,0.96,30.2,M,-8.8,M,,*5A
index 785de58907775b03f9f689b66d221016a6c73426..01b048513f145645c5757bb1d12db4602873101a 100644 (file)
@@ -39,3 +39,7 @@ gpsbabel -t -i nmea -f ${REFERENCE}/track/addmultipledaysbkw.nmea -o unicsv,utc=
 compare ${REFERENCE}/track/addmultipledays.csv ${TMPDIR}/addmultipledaysbkw.csv
 gpsbabel -t -i nmea -f ${REFERENCE}/track/addmultipledaysmid.nmea -o unicsv,utc=0 -F ${TMPDIR}/addmultipledaysmid.csv
 compare ${REFERENCE}/track/addmultipledays.csv ${TMPDIR}/addmultipledaysmid.csv
+
+# test date time parsing
+gpsbabel -t -i nmea -f ${REFERENCE}/track/nmeadatetime.nmea -o unicsv,utc=0 -F ${TMPDIR}/nmeadatetime.csv
+compare ${REFERENCE}/track/nmeadatetime.csv ${TMPDIR}/nmeadatetime.csv